#include "Motor.h"
#include "app_trace.h"
#include "app_util_platform.h"
#include "board_cfg.h"
#include "display_ctrl.h"
#include "display_drv.h"
#include "nrf_delay.h"
#include "nrf_drv_common.h"
#include "nrf_gpio.h"
#include "nrf_spi.h"
#include "nrf_spim.h"
#define LOG(fmt, ...) //app_trace_log(fmt "\r\n", ##__VA_ARGS__)

void lcd_set_xy_without_data(uint16_t Xstart, uint16_t Xend, uint16_t Ystart, uint16_t Yend)
{
    Xstart += LCD_X_OFFSET;
    Xend += LCD_X_OFFSET;
    uint8_t buffer[4] = {Xstart >> 8, Xstart & 0xff, Xend >> 8, Xend & 0xff};
    oled_write_cmd(0x2a);
    oled_write_data_bytes(buffer, 4);

    oled_write_cmd(0x2b);
    buffer[0] = Ystart >> 8;
    buffer[1] = Ystart & 0xff;
    buffer[2] = Yend >> 8;
    buffer[3] = Yend & 0xff;
    oled_write_data_bytes(buffer, 4);
}

void lcd_set_xy(uint16_t Xstart, uint16_t Xend, uint16_t Ystart, uint16_t Yend)
{
    // LOG("set xy %d,%d %d,%d", Xstart, Ystart, Xend, Yend);
    lcd_set_xy_without_data(Xstart, Xend, Ystart, Yend);
    oled_write_cmd(0x2c);
}
void lcd_set_ram_offset(uint16_t offset)
{
    offset = (offset + LCD_RAM_DEFAULT_OFFSET) % OLED_RAM_Y_MAX;
#ifdef SCREEN_XY_MIRROR
    offset = OLED_RAM_Y_MAX - offset;
#endif
    // LOG("%d", offset);
    oled_write_cmd(0x37);
    oled_write_data(offset >> 8);
    oled_write_data(offset & 0xFF);
}

// static void lcd_test()
// {
//     peripheral_oledpower_On();
//     LOG("test start");
//     oled_write_cmd(0x29);
//     oled_write_cmd(0x11); // sleep out
//     nrf_delay_ms(5);

//     lcd_set_ram_offset(0);
//     // oled_all_fill_data(RGB565_COLOR_BLACK);
//     // nrf_delay_ms(1000);
//     // oled_all_fill_data(RGB565_COLOR_WHITE);
//     // nrf_delay_ms(1000);
//     // oled_all_fill_data(RGB565_COLOR_BLACK);
//     // nrf_delay_ms(1000);
//     oled_all_fill_data(RGB565_COLOR_RED);
//     nrf_delay_ms(1000);
// }
void lcd_drv_set_param(void)
{
    oled_write_cmd(0x11); // Sleep out
    nrf_delay_us(200);    // Delay 120ms
    oled_write_cmd(0xB1); // 刷新频率
    oled_write_data(0x05);
    oled_write_data(0x3C);
    oled_write_data(0x3C);

    oled_write_cmd(0xB2);
    oled_write_data(0x05);
    oled_write_data(0x3C);
    oled_write_data(0x3C);

    oled_write_cmd(0xB3);
    oled_write_data(0x05);
    oled_write_data(0x3C);
    oled_write_data(0x3C);
    oled_write_data(0x05);
    oled_write_data(0x3C);
    oled_write_data(0x3C);

    oled_write_cmd(0xB4); // Dot inversion
    oled_write_data(0x03);

    oled_write_cmd(0xC0);
    oled_write_data(0x0E);
    oled_write_data(0x0E);
    oled_write_data(0x04);

    oled_write_cmd(0xC1);
    oled_write_data(0xC5);

    oled_write_cmd(0xC2);
    oled_write_data(0x0d);
    oled_write_data(0x00);

    oled_write_cmd(0xC3);
    oled_write_data(0x8D);
    oled_write_data(0x2A);

    oled_write_cmd(0xC4);
    oled_write_data(0x8D);
    oled_write_data(0xEE);

    oled_write_cmd(0xC5);  // VCOM
    oled_write_data(0x06); // 1D  .06

    oled_write_cmd(0x36); // MX, MY, RGB mode, RGB 0xC0, BGR 0xC8
                          // #if defined(C68)
                          //     oled_write_data(0x08);
                          // #else
                          //     oled_write_data(0xC8);
                          // #endif
#ifdef SCREEN_XY_MIRROR
    oled_write_data(0xc8);
#else
    oled_write_data(0x08);
#endif
    oled_write_cmd(0x3A); // 设置RGB565 RGB666 RGB444
    oled_write_data(0x05);

    oled_write_cmd(0xE0);
    oled_write_data(0x0b);
    oled_write_data(0x17);
    oled_write_data(0x0a);
    oled_write_data(0x0d);
    oled_write_data(0x1a);
    oled_write_data(0x19);
    oled_write_data(0x16);
    oled_write_data(0x1d);
    oled_write_data(0x21);
    oled_write_data(0x26);
    oled_write_data(0x37);
    oled_write_data(0x3c);
    oled_write_data(0x00);
    oled_write_data(0x09);
    oled_write_data(0x05);
    oled_write_data(0x10);

    oled_write_cmd(0xE1);
    oled_write_data(0x0c);
    oled_write_data(0x19);
    oled_write_data(0x09);
    oled_write_data(0x0d);
    oled_write_data(0x1b);
    oled_write_data(0x19);
    oled_write_data(0x15);
    oled_write_data(0x1d);
    oled_write_data(0x21);
    oled_write_data(0x26);
    oled_write_data(0x39);
    oled_write_data(0x3E);
    oled_write_data(0x00);
    oled_write_data(0x09);
    oled_write_data(0x05);
    oled_write_data(0x10);

    // oled_write_cmd(0x21);
    lcd_set_ram_offset(disp_ctrl.last_y_offset);
    lcd_set_xy_without_data(0, OLED_SIZE_X - 1, 0, OLED_SIZE_Y - 1);
}
void lcd_drv_init(void)
{
    oled_spi_init(SPI_CFG_MODE_HARDWARE_DMA);
    nrf_gpio_cfg_output(OLED_DC_PIN);

#if USE_OLED_RESET
    nrf_gpio_pin_write(OLED_RESET_PIN, 1);
    nrf_delay_ms(5);

    nrf_gpio_pin_write(OLED_RESET_PIN, 0);
    nrf_delay_us(10);

    nrf_gpio_pin_write(OLED_RESET_PIN, 1);
    nrf_delay_ms(120);
#endif
    lcd_drv_set_param();
    // lcd_test();
}

void oled_turn_off(void)
{
    oled_write_cmd(0x28);
    oled_write_cmd(0x10); // sleep in
    nrf_delay_ms(120);
}

void oled_turn_on(void)
{
    lcd_drv_set_param();
    oled_write_cmd(0x29);
    oled_write_cmd(0x11); // sleep out
    nrf_delay_ms(5);
}

void oled_all_fill_data(uint16_t data)
{
    lcd_set_xy(0, OLED_SIZE_X - 1, 0, OLED_SIZE_Y - 1);

    nrf_gpio_pin_clear(OLED_CS_PIN);
    nrf_gpio_pin_set(OLED_DC_PIN);
    uint8_t buffer[2] = {data >> 8, data & 0xff};
    if (get_spi_mode() == SPI_CFG_MODE_SOFTWARE)
    {
        for (uint16_t i = 0; i < OLED_SIZE_X * OLED_SIZE_Y; i++)
        {
            oled_spi_tx_byte(buffer[0]);
            oled_spi_tx_byte(buffer[1]);
        }
    }
    else
    {
        for (uint16_t i = 0; i < OLED_SIZE_X * OLED_SIZE_Y; i++)
        {
            oled_spi_tx_bytes_hw(buffer, 2);
        }
    }

    oled_spi_hw_wait_end();
    nrf_gpio_pin_set(OLED_CS_PIN);
}

void oled_fill_data(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint8_t *p_data)
{
    lcd_set_xy(x, x + w - 1, y, y + h - 1);
    if (get_spi_mode() != SPI_CFG_MODE_SOFTWARE)
    {
        spi_switch_mode(SPI_CFG_MODE_HARDWARE_DMA);
    }
    nrf_gpio_pin_clear(OLED_CS_PIN);
    nrf_gpio_pin_set(OLED_DC_PIN);

    uint16_t *color = (uint16_t *)p_data;
    uint16_t cnt = w * h;
    for (uint16_t i = 0; i < h; i++)
    {
        for (uint16_t j = 0; j < w * 2; j += 2)
        {
            *color = __REV16(*color);
            color++;
        }
    }
    if (get_spi_mode() == SPI_CFG_MODE_SOFTWARE)
    {
        // for (uint16_t i = 0; i < h; i++)
        // {
        //     for (uint16_t j = 0; j < w * 2; j += 2)
        //     {
        //         *color = __REV16(*color);
        //         color++;
        //     }
        // }
        for (uint16_t i = 0; i < h; i++)
        {
            for (uint16_t j = 0; j < w * 2; j += 2)
            {
                oled_spi_tx_byte(p_data[j + 1]);
                oled_spi_tx_byte(p_data[j]);
            }
            p_data += w * 2; // 2字节
        }
    }
    else if (get_spi_mode() == SPI_CFG_MODE_HARDWARE_DMA)
    {
        spim_tx(p_data, w, h * 2 - 1);
        // spim_wait_finish();
    }
    else
    {
        oled_spi_tx_bytes_hw(p_data, cnt * 2);
        oled_spi_hw_wait_end();
        nrf_gpio_pin_set(OLED_CS_PIN);
    }
}

void oled_fill_data_continue(uint16_t w, uint16_t h, const uint8_t *p_data)
{
    if (get_spi_mode() != SPI_CFG_MODE_SOFTWARE)
    {
        spi_switch_mode(SPI_CFG_MODE_HARDWARE_DMA);
    }
    nrf_gpio_pin_clear(OLED_CS_PIN);
    nrf_gpio_pin_set(OLED_DC_PIN);

    uint16_t cnt = w * h;
    uint16_t *color = (uint16_t *)p_data;
    for (uint16_t i = 0; i < h; i++)
    {
        for (uint16_t j = 0; j < w * 2; j += 2)
        {
            *color = __REV16(*color);
            color++;
        }
    }
    if (get_spi_mode() == SPI_CFG_MODE_SOFTWARE)
    {
        // for (uint16_t i = 0; i < h; i++)
        // {
        //     for (uint16_t j = 0; j < w * 2; j += 2)
        //     {
        //         *color = __REV16(*color);
        //         color++;
        //     }
        // }
        for (uint16_t i = 0; i < h; i++)
        {
            for (uint16_t j = 0; j < w * 2; j += 2)
            {
                oled_spi_tx_byte(p_data[j + 1]);
                oled_spi_tx_byte(p_data[j]);
            }
            p_data += w * 2; // 2字节
        }
    }
    else if (get_spi_mode() == SPI_CFG_MODE_HARDWARE_DMA)
    {
        spim_tx(p_data, w, h * 2 - 1);
        // spi_switch_mode(SPI_CFG_MODE_HARDWARE);
    }
    else
    {
        oled_spi_tx_bytes_hw(p_data, cnt * 2);
        oled_spi_hw_wait_end();
        nrf_gpio_pin_set(OLED_CS_PIN);
    }
}
